package com.similarworld.jsf;

import java.text.MessageFormat;

import javax.el.ELContext;
import javax.el.ExpressionFactory;
import javax.el.ValueExpression;
import javax.faces.application.Application;
import javax.faces.application.FacesMessage;
import javax.faces.application.FacesMessage.Severity;
import javax.faces.context.FacesContext;

public class MessageUtils {

	/**
	 * Mesaj bundledan key ile alinan mesaji args ile formatlayarak doner
	 * 
	 * @param key
	 * @param args
	 * @return mesaj
	 */
	public static String getMessage(String key, Object... args) {
		return MessageFormat.format(getMessage(key), args);
	}
	
	/**
	 * Mesaj bundledan key ile alinan mesaji doner
	 * 
	 * @param key
	 * @return mesaj
	 */
	public static String getMessage(String key) {
		Object msg = resolveExpression("#{messages['" + key + "']}");
		
		if (msg != null)
			return (String) msg;
		else
			return "";
	}
	
	/**
	 * Mesaj bundledan key ile alinan mesaji FacesMessages a ekler
	 * 
	 * @param key
	 */
	public static void addFacesMessageByKey(String key) {
		addFacesMessageByMessage(getMessage(key));
	}
	
	/**
	 * Mesaj bundledan key ile alinan mesaji args ile formatlayarak FacesMessages a ekler
	 * 
	 * @param key
	 * @param args
	 */
	public static void addFacesMessageWithArgs(String key, Object... args) {
		String msg = getMessage(key);
		String message = MessageFormat.format(msg, args);
		
		addFacesMessageByMessage(message);
	}
	
	/**
	 * FacesMessages a mesaj ekler
	 * 
	 * @param message
	 */
	public static void addFacesMessageByMessage(String message) {
		if (isFacesNull()) return;
		
		FacesContext
			.getCurrentInstance()
				.addMessage(null, 
					new FacesMessage(message));
	}
	
	/**
	 * FacesMessages a seviye ile mesaj ekler
	 * 
	 * @param message
	 */
	public static void addFacesMessageByMessage(Severity severity, String message) {
		if (isFacesNull()) return;
		
		FacesContext
			.getCurrentInstance()
				.addMessage(null, 
					new FacesMessage(severity, message, null));
	}
	
	/**
	 * FacesMessages a mesaji args ile formatlayarak ekler
	 * 
	 * @param message
	 */
	public static void addFacesMessageByKey(String key, Object... args) {
		if (isFacesNull()) return;
		
		String msg = getMessage(key);
		String message = MessageFormat.format(msg, args);

		FacesContext
			.getCurrentInstance()
				.addMessage(null, 
					new FacesMessage(FacesMessage.SEVERITY_INFO, message, null));
	}
	
	/**
	 * FacesMessages a seviye ile mesaji args ile formatlayarak ekler
	 * 
	 * @param message
	 */
	public static void addFacesMessageByKey(Severity severity, String key, Object... args) {
		if (isFacesNull()) return;
		
		String msg = getMessage(key);
		String message = MessageFormat.format(msg, args);

		FacesContext
			.getCurrentInstance()
				.addMessage(null, 
					new FacesMessage(severity, message, null));
	}
	
	public static Object resolveExpression(String expression) {
		FacesContext facesContext = FacesContext.getCurrentInstance();
		
		if (facesContext != null) {
			Application app = facesContext.getApplication();
			ExpressionFactory elFactory = app.getExpressionFactory();
			ELContext elContext = facesContext.getELContext();
			ValueExpression valueExp = elFactory.createValueExpression(elContext, expression, Object.class);
			
			return valueExp.getValue(elContext);
		} else {
			return null;
		}
	}

	private static boolean isFacesNull() {
		return (FacesContext.getCurrentInstance() == null);
	}
	
}
